// 析构函数中检查线程是否可加入
#include <iostream>
#include <thread>

class joining_thread {
    std::thread t;
public:
    joining_thread() noexcept = default; // 不会抛异常

    template<typename Callable, typename ... Args>
    explicit joining_thread(Callable&& func, Args&& ... args) :
        t(std::forward<Callable>(func), std::forward<Args>) { }

    explicit joining_thread(std::thread t_) noexcept:
        t(std::move(t_)) { }

    // 拷贝构造
    joining_thread(joining_thread&& other) noexcept: 
        t(std::move(other.t)) { }
    // 赋值构造，对象传递
    joining_thread& operator=(joining_thread&& other) noexcept {
        if (joinable()) {
            join();
        }
        std::move(other.t);
        return *this;
    }
    // 赋值构造，thread直接传递
    joining_thread& operator=(std::thread other) noexcept {
        if (joinable()) {
            join();
        } 
        t = std::move(other);
        return *this;
    }
    ~joining_thread() noexcept {
        if (joinable()) {
            join();
        }
    }
    // 线程交换，将传入线程和本地线程交换
    void swap(joining_thread& other) noexcept {
        t.swap(other.t);
    }
    bool joinable() const noexcept {
        return t.joinable();
    }
    void join() {
        t.join();
    }
    void detach() {
        t.detach();
    }
    std::thread& as_thread() noexcept {
        return t;
    }
    const std::thread& as_thread() const noexcept {
        return t;
    }
};
